# vim:fileencoding=utf-8
# vim:encoding=utf-8
# 
import os, sys, re, xml.parsers.expat

class Parser:
	def __init__(self):
		self.parser = xml.parsers.expat.ParserCreate()
		self.parser.StartElementHandler = self.start_element
		self.parser.EndElementHandler   = self.end_element
		self.parser.CharacterDataHandler= self.char_data
		self.tree = list('/')
		self.para = list()
		self.tabsize = 8
		self.tran={}
		self.tran['name']='名称'
		self.tran['lib']='库'
		self.tran['syno']='概要'
		self.tran['desc']='详述'
		self.tran['return']='返回值'
		self.tran['examples']='例'
		self.tran['errors']='错误'
		self.tran['see']='参见'
		self.tran['coderef']='代码引用'
		self.tran['standards']='标准'
		self.tran['history']='历史'
		self.tran['bugs']='臭虫'
		self.tran['authors']='作者'
		self.tran['impl']='实现笔记'
		self.tran['notes']='笔记'
		self.tran['security']='安全'
		self.tran['restrictions']='限制'
		self.space = '&nbsp;'*self.tabsize
		self.catspace = ' '*self.tabsize

		self.style={}
		self.style['type'] = '<font color="red">%s</font>'
		self.style['number'] = '<font color="blue">%s</font>'
		self.style['paraname'] = '<font color="green">%s</font>'
		self.style['funcname'] = '<font color="blue">%s</font>'
		self.style['include'] = '&lt;<font color="dark">%s</font>&gt;'
		self.catstyle={}
		self.catstyle['type'] = '<font color="red">%s</font>'
		self.catstyle['number'] = '<font color="blue">%s</font>'
		self.catstyle['paraname'] = '<font color="green">%s</font>'
		self.catstyle['funcname'] = '<font color="blue">%s</font>'
		self.catstyle['include'] = '&lt;<font color="dark">%s</font>&gt;'

	def deal(self, s):
		p, t = os.path.splitext(s)
		self.htmlfile = open(p+'.html', 'w')
		#self.catfile  = open(p[:-3]+'.0', 'w')

		self.htmlfile.write("""<html>
				<head>
				<meta http-equiv="content-type" content="text/html; charset=UTF-8">
				</head>
				<body>""")
		self.parser.ParseFile(open(s))
		self.htmlfile.write('</body></html>')
		self.htmlfile.close()

	def start_element(self, name, attrs):
		self.data = ''
		if name == 'head':
			self.htmlfile.write('<pre>\n')
			pass
		elif name == 'func':
			#self.catfile.write('\n'+self.catspace+attrs['type']+' '+attrs['name']+'(')
			self.htmlfile.write('\n'+self.space+self.style['type']%attrs['type']+' '+self.style['funcname']%attrs['name']+'(')
			self.paranum = 0
		elif name == 'para':
			if self.paranum:
				self.htmlfile.write(', ')
				#self.catfile.write(', ')
			if attrs['type'] == 'void' or len(attrs['type']) == 0 or len(attrs['name']) == 0:
				#self.catfile.write(attrs['type'])
				self.htmlfile.write(self.style['type']%attrs['type'])
			else:
				self.para.append(attrs['name'])
				#self.catfile.write(attrs['type']+' '+attrs['name'])
				self.htmlfile.write(self.style['type']%attrs['type']+' '+self.style['paraname']%attrs['name'])
		elif name == 'include':
			#self.catfile.write(self.catspace+'#include ')
			self.htmlfile.write(self.space+'#include ')
			pass
		elif self.tran.has_key(name):
			#self.catfile.write(self.tran[name]+'\n')
			self.htmlfile.write('<pre>\n')
			self.htmlfile.write('<b>'+self.tran[name]+'</b>:\n')

		self.tree.append(name)

	def end_element(self, name):
		self.deal_data()
		self.data = ''
		self.tree.pop()
		if name == 'include':
			#self.catfile.write('\n')
			self.htmlfile.write('\n')
		elif name == 'para':
			self.paranum += 1
		elif name == 'func':
			#self.catfile.write('); ')
			self.htmlfile.write('); ')
		elif name == 'syno':
			self.htmlfile.seek(-1, 1)
			self.htmlfile.write('</pre>\n')
			#self.catfile.write('\n')
		else:
			#self.catfile.write('\n')
			self.htmlfile.write('</pre>\n')
		pass

	def char_data(self, data):
		self.data += data.strip(' \t')
		pass
	def deal_data(self):
		data = self.data
		catdata = data
		if self.tree[-1] not in ('errors', 'return'):
			data = re.sub('\t+', ' ', data)
			catdata = re.sub('\t+', ' ', catdata)
		data = re.sub(r'<', r'&lt;', data)
		data = re.sub(r'>', r'&gt;', data)
		data = re.sub(r'[ ]{2,}', ' ', data)
		catdata = re.sub(r'[ ]{2,}', ' ', catdata)
		data = re.sub(r'(^ *\n)+', r'\n', data)
		catdata = re.sub(r'(^ *\n)+', r'\n', catdata)
		data = data.rstrip('\n \t')
		data = data.lstrip('\n \t')
		catdata = catdata.rstrip('\n \t')
		catdata = catdata.lstrip('\n \t')
		data = re.sub('\n', '\n'+self.space, data)
		catdata = re.sub('\n', '\n'+self.catspace, catdata)

		#data = re.sub(r'([^(])([-]?[0-9]+\.?[0-9]*)([^)])', r'\1'+self.style['number'].replace('%s', r'\2')+r'\3', data)
		for i in self.para:
			data = re.sub(r'([^a-zA-Z_0-9])%s([^a-zA-Z_0-9])'%i, r'\1'+self.style['paraname']%i+r'\2', data)

		data = re.sub(r'([a-zA-Z_][a-zA-Z_0-9]*)\(([0-9])\)', 
				r'<a href="http://www.freebsd.org/cgi/man.cgi?query=\1&sektion=\2&apropos=0&manpath=FreeBSD+6.1-RELEASE">\1(\2)</a>', data)
		data = re.sub(r'([a-zA-Z_][a-zA-Z_0-9]*\(\))', r'<font color=blue>\1</font>', data)
		data = re.sub(r'{color=([^}]+)}(.*?){/color}', r'<font color=\1>\2</font>', data)
		catdata = re.sub(r'{color=[^}]+}', r'', catdata)
		catdata = re.sub(r'{/color}', r'', catdata)
		catdata = re.sub(r'{/?[uib]}', r'', catdata)
		while(re.search(r'{([uib])}.*?{/\1}', data, re.M)):
			data = re.sub(r'{([uib])}(.*?){/\1}', r'<\1>\2</\1>', data)
		data = re.sub(r'{tab}', self.space, data)
		catdata = re.sub(r'{tab}', self.catspace, catdata)
		data = re.sub(r'([a-zA-Z_/]+[a-zA-Z]+\.h)', self.style['include'].replace('%s', r'\1'), data)
		if self.tree[-1]=='include':
			self.htmlfile.write(data.encode('utf-8'))
			#self.catfile.write(catdata.encode('utf-8'))
		elif len(data):
			self.htmlfile.write(self.space+data.encode('utf-8'))
			#self.catfile.write(self.catspace+catdata.encode('utf-8'))


if __name__ == '__main__':
	if len(sys.argv)!=2:
		print 'Usage\n  %s xmlfile.xml \n'%sys.argv[0]
		sys.exit(1)
	else:
		xmlfile = sys.argv[1]
	p = Parser()
	p.deal(xmlfile)
